/*
 * @Author: HeAo
 * @Date: 2022-08-18 19:07:30
 * @LastEditTime: 2022-08-19 10:41:50
 * @LastEditors: HeAo
 * @Description: 
 * @FilePath: \JavaScripe\day-09\04-原型模式.js
 * 别乱动！
 */
/*
原理:实例对象会继承原型对象中的方法,写在原型中也不会打破全局作用域
目的:为了解决将构造函数方法外移产生的问题
方法:因为每个构造函数都会创建一个prototype属性(原型属性)具体可以参考对象中的原型解释
因此在构造函数给实例对象赋值,也可以给他们的原型赋值
*/
// 1.定义它Person()函数 
function Person() {}
// 3.将数据写入原型对象中   写死赋值:类似于我们的var name='zhangsan'
Person.prototype.name = 'zhangsan'
Person.prototype.age = 12
Person.prototype.sayName = function () {
  console.log(this.name); //this 谁调用this指向谁
}

// 2.通过new说明Person是一个构造函数
var p1 = new Person()
var p2 = new Person()
// console.log(p1.name, p2.name); //zhangsan zhangsan 说明p1 p2都是继承同一个原型
// // 检测是否解决问题
// console.log(p1.sayName === p2.sayName); //true 

// function Animal() {}
// var a1 = new Animal()
// console.log(a1.sayName === p1.sayName); //false

// console.log(p1.constructor === Object); //false
// console.log(p1.constructor === Person); //true  constructor属性指向Person对象

// // 如何定义自己的值,而不继承? 直接定义覆盖
p2.name = 'lisi'
console.log(p2.name); //lisi

// // 判断该属性,是否是自己的属性
// console.log(p2.hasOwnProperty('name')); //true
// console.log(p1.hasOwnProperty('name')); //false  因为p1没有重新赋值,仍是继承原型

// // 判断一个属性是否是原型属性
function hasPrototypeProperty(object, name) {
  return !object.hasOwnProperty(name) && (name in object)
}
console.log(hasPrototypeProperty(p1, 'name')); //true 说明p1的name是原型属性









// function Person.prototype.sayName() {} //为什么报错?